import axios from 'axios'
import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from '@/utils/ruoyi'
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import { useUserStore } from '@/store/modules/user'
import { removeToken } from '@/utils/auth'
let downloadLoadingInstance
export let isRelogin = { show: false }


// 创建 axios 实例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 3000000,
  withCredentials: true
})

// 自动判断Content-Type类型
function getContentType(data) {
  if (data instanceof FormData) {
    return 'multipart/form-data'
  }
  if (data instanceof URLSearchParams) {
    return 'application/x-www-form-urlencoded'
  }
  if (Object.prototype.toString.call(data) === '[object File]' ||
    Object.prototype.toString.call(data) === '[object Blob]') {
    return 'multipart/form-data'
  }
  return 'application/json'
}

// 自动处理请求数据
function transformRequestData(data, contentType) {
  if (!data) return data

  if (contentType.includes('multipart/form-data')) {
    if (data instanceof FormData) {
      return data
    }
    const formData = new FormData()
    Object.entries(data).forEach(([key, value]) => {
      if (Array.isArray(value)) {
        value.forEach(item => formData.append(`${key}[]`, item))
      } else {
        formData.append(key, value)
      }
    })
    return formData
  }

  if (contentType.includes('application/x-www-form-urlencoded')) {
    if (data instanceof URLSearchParams) {
      return data
    }
    return tansParams(data)
  }

  if (contentType.includes('application/json')) {
    return JSON.stringify(data)
  }

  return data
}

// request 拦截器
service.interceptors.request.use(
  config => {
    const userStore = useUserStore()

    // 是否需要设置 token
    const isToken = (config.headers || {}).isToken === false
    // 是否需要防止数据重复提交
    const isRepeatSubmit = (config.headers || {}).repeatSubmit === false

    // 设置token
    if (getToken() && !isToken) {
      config.headers = {
        ...config.headers,
        'Authorization': `Bearer ${userStore.token}`
      }
    }

    // get请求映射params参数
    if (config.method === 'get' && config.params) {
      let url = config.url + '?' + tansParams(config.params)
      url = url.slice(0, -1)
      config.params = {}
      config.url = url
    }

    // POST 和 PUT 请求处理
    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
      // 自动设置Content-Type
      const contentType = config.headers['Content-Type'] || getContentType(config.data)
      config.headers['Content-Type'] = contentType

      // 转换请求数据
      if (config.data && typeof config.data === 'object') {
        config.data = transformRequestData(config.data, contentType)
      }

      // 防重复提交处理
      const requestObj = {
        url: config.url,
        data: typeof config.data === 'string' ? config.data : JSON.stringify(config.data),
        time: new Date().getTime()
      }

      const requestSize = new Blob([requestObj.data]).size
      const limitSize = 5 * 1024 * 1024

      if (requestSize >= limitSize) {
        console.warn(`[${config.url}]: 请求数据大小超出允许的5M限制，无法进行防重复提交验证。`)
        return config
      }

      const sessionObj = cache.session.getJSON('sessionObj')
      if (!sessionObj) {
        cache.session.setJSON('sessionObj', requestObj)
      } else {
        const { url: s_url, data: s_data, time: s_time } = sessionObj
        const interval = 1000

        if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
          const message = '数据正在处理，请勿重复提交'
          console.warn(`[${s_url}]: ${message}`)
          return Promise.reject(new Error(message))
        }
        cache.session.setJSON('sessionObj', requestObj)
      }
    }
    return config
  },
  error => {
    console.error('Request error:', error)
    return Promise.reject(error)
  }
)

// response 拦截器
service.interceptors.response.use(
  response => {
    // 二进制数据直接返回
    if (response.request.responseType === 'blob' || response.request.responseType === 'arraybuffer') {
      return response.data
    }

    const code = response.data.code || '00000'
    const msg = errorCode[code] || response.data.msg || errorCode['default']

    // 处理不同状态码
    switch (code) {
      case '00000':
        return handleSuccessResponse(response.data)
      case '401':
        return handleUnauthorized(msg)
      case '500':
        ElMessage({ message: msg, type: 'error' })
        return Promise.reject(new Error(msg))
      case '601':
        ElMessage({ message: msg, type: 'warning' })
        return Promise.reject(new Error(msg))
      default:
        ElNotification.error({ title: msg })
        return Promise.reject('error')
    }
  },
  error => {
    console.error('Response error:', error)
    // 401: 未登录或Token过期或者已停用
    const message = handleErrorMessage(error)
    ElMessage({ message, type: 'error', duration: 5 * 1000 })
    if (error.response.status === 401) {
      console.log(1);
      removeToken();
      Cookies.remove('Admin-token');
      router.replace('/login');
    }
    return Promise.reject(error)
  }
)

function handleSuccessResponse(responseData) {
  try {
    if (typeof responseData === 'string') {
      responseData = JSON.parse(responseData)
    }
    return {
      ...responseData,
      sdata: { ...responseData },
      rdata: { ...responseData },
      defaultData: { ...responseData }
    }
  } catch (error) {
    console.error('数据处理错误:', error)
    return responseData
  }
}

function handleUnauthorized(msg) {
  console.log('Unauthorized:', msg);

  if (!isRelogin.show) {
    isRelogin.show = true
    ElMessageBox.confirm('登录状态已过期，您可以继续留在该页面，或者重新登录', '系统提示', {
      confirmButtonText: '重新登录',
      cancelButtonText: '取消',
      type: 'warning'
    })
      .then(() => {
        isRelogin.show = false
        useUserStore()
          .logOut()
          .then(() => {
            location.href = '/index'
          })
      })
      .catch(() => {
        isRelogin.show = false
      })
  }
  return Promise.reject('无效的会话，或者会话已过期，请重新登录。')
}

function handleErrorMessage(error) {
  console.log('Error:', error)
  const message = error.response?.data?.msg
  if (message === 'Network Error') return '后端接口连接异常'
  if (message.includes('timeout')) return '系统接口请求超时'
  if (message.includes('Request failed with status code')) {
    return `系统接口${message.slice(-3)}异常`
  }
  return message
}

// 通用下载方法
export function download(url, params, filename, config) {
  downloadLoadingInstance = ElLoading.service({
    text: "正在下载数据，请稍候",
    background: "rgba(0, 0, 0, 0.7)"
  })

  return service.post(url, params, {
    transformRequest: [(params) => tansParams(params)],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob',
    ...config
  }).then(async (data) => {
    const isBlob = blobValidate(data)
    if (isBlob) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text()
      const rspObj = JSON.parse(resText)
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      ElMessage.error(errMsg)
    }
  }).catch((r) => {
    console.error('Download error:', r)
    ElMessage.error('下载文件出现错误，请联系管理员！')
  }).finally(() => {
    downloadLoadingInstance.close()
  })
}

export default service